<?php

class UserController extends Zend_Controller_Action {
	
	private $user;
	private $message;
	private $userMessage;
	
	
	/*********************************************************************
	 *  PRIVATE FUNCTIONS
	 *********************************************************************/	
		
	 /**
     * Post profile message, log user activity
     * 
     * @param $send_user_id user that post the message
     * @param $target_user_id user that receive the message
     * @param $comment message
     */
    private function postusermessage($post_user_id, $target_user_id, $comment, $type){
    	
    	$db = Zend_Registry::get ( 'db' );
		$db->beginTransaction ();
				
		$data = array ('user_id' => $post_user_id, 'message' => $comment, 'created' => $this->_helper->generator->generateCurrentTime () );
		$message_id = $this->message->postMessage ( $data );
		$data = array ('message_id' => $message_id, 'target_user_id' => $target_user_id, 'type' => $type, 'created' => $this->_helper->generator->generateCurrentTime () );
		$userMessage = $this->userMessage->addUserMessage ( $data );
		
		// add activity log
		Activity::logActivity ( Activity::PROFILE_POST, $post_user_id, $userMessage, $this->_helper->generator->generateCurrentTime () );
		
		$data = array(
			EmailMessageTemplate::TAG_SEND_USER => User::findById($post_user_id)->email,
		);
		MailQueue::addToQueue(
			Activity::PROFILE_POST, 
			'您的朋友给你留言了', 
			UserMessage::getUser(UserMessage::findById($userMessage))->email, 
			EmailMessageTemplate::getMessage(Activity::PROFILE_POST, $data), 
			$this->_helper->generator->generateCurrentTime());
		$db->commit ();
    }
    
	
    private function profilepostmessage($post_user_id, $target_user_id, $comment){   	
		$type = UserMessage::PUBLIC_MESSAGE;
		$this->postusermessage($post_user_id, $target_user_id, $comment, $type);
    }
    
	/*********************************************************************
	 *  COMMON ACTIONS
	 *********************************************************************/	
       	
	public function init() {
		$this->user = new User ( );
		$this->message = new Message ( );
		$this->userMessage = new UserMessage ( );
	}
	
	/**
	 * User profile page.
	 * 
	 * 1) If the user is logged in
	 * 1 a) If uid is given -> profileUser equals uid
	 *     A) If loggedInUser is friend with the profileUser Show post message form
	 *     B) If not friends with prorfileUser don't show post messageForm
	 *   b) If uid is not given -> profileUser equals loggedInUser Show post message form
	 * 
	 * 2) If the user is not logged in
	 * 2 a) If uid is given -> show limited information about this profileUser
	 *   b) If uid is not given -> redirect to login page
	 * 
	 * 
	 * Leave message to his profile, 
	 * everyone can see profile page, but only friend can leave message
	 * 
	 * Show friend request.
	 * 
	 */
	public function indexAction() {
		
		if ($this->_helper->user->isLoggedIn ()) {
			$loggedInUser = User::findById ($this->_helper->user->getUserData()->id);
		
			if ($this->_getParam ( 'uid' )) { //1a
				$user = User::findById ( $this->_getParam ( 'uid' ) );
			} else { //1b
				$user = $loggedInUser;
			}
			
			//TODO Shouldn't this be a static method?
			$invitation = new Invitation ();
			$invitations = $invitation->findInvitationByUser ( $user->id );
			
			$this->view->invitations = $invitations;
			$this->view->user = $user;
			$this->view->pageTitle = $user->username . "的档案";
			
			$config = Zend_Registry::get ( 'config' );
			$this->view->headScript ()->appendFile ( $config->baseurl . '/js/jquery.address-1.1.min.js' );
			$this->view->headScript ()->appendFile ( $config->baseurl . '/js/profile.js' );
			
			
			if (User::isFriend ( $loggedInUser, $user ) 
				|| $user->id == $loggedInUser->id) { // 1aA or 1b
					
				$profileMessageForm = new ProfileMessageForm($loggedInUser->id,$user->id);
				$this->view->profileMessageForm = $profileMessageForm;
				
				//For NonJS implementation
				if ($this->getRequest ()->isPost ()) {
				if ($profileMessageForm->isValid ( $_POST )) {
					$post_user_id = $profileMessageForm->getValue ( 'post_user_id' );
					$target_user_id = $profileMessageForm->getValue ( 'target_user_id' );
					$comment = $profileMessageForm->getValue ( 'comment' );					
					$this->profilepostmessage($post_user_id, $target_user_id, $comment);
					$this->_redirect ( $this->_request->getPost ( 'return' ) );
				}
			}
					
			} else { //1aB
			
				$this->view->canInvite=true;
				$this->getResponse()->appendBody("CAN*T POST ANYTHING HERE!");
			}
									
		} else {
		
			if ($this->_getParam ( 'uid' )) { //2a
				$user = User::findById ( $this->_getParam ( 'uid' ) );
								
				// show limited info about this person
				$this->getResponse()->appendBody("THIS IS LIMITED VERSION OF THIS USER!");
				
			} else { //2b
				$this->_redirect ( 'user/login' );
			}
		}
	
	}
	
	public function registerAction() {
		
		$config = Zend_Registry::get ( 'config' );
		$this->view->headScript ()->appendFile ( $config->baseurl . '/js/jquery.validate.min.js' );
		$this->view->headScript ()->appendFile ( $config->baseurl . '/js/register.js' );
		
		$this->view->pageTitle = "请您注册";
		$this->view->pageTitleClass = "register";
		
		$user = User::findById ( $this->getRequest ()->getParam ( 'uid' ) );
		$form = new RegisterForm ( $user );
		$this->view->form = $form;
		
		if ($this->getRequest ()->isPost ()) {
			if ($form->isValid ( $_POST )) {
				$user = new User ( );
				$username = $form->getValue ( 'username' );
				$email = $form->getValue ( 'email' );
				$password = $form->getValue ( 'password' );
				$confirm = $form->getValue ( 'confirm' );
				$hasEmail = $form->getValue ( 'hasemail' );
				if ($password != $confirm) {
					$this->view->errorMessage = "Password and confirm password don’t match.";
					return;
				}
				
				$registrationKey = $this->_helper->generator ( 32, 'alpha' );
				if ($hasEmail == 1) {
					$data = array (
						'username' => $username, 
						'password' => md5 ( $password ), 
						'registration_key' => $registrationKey, 
						'created' => $this->_helper->generator->generateCurrentTime () );
					$where = $user->getAdapter ()->quoteInto ( 'email = ?', $email );
					$user->update ( $data, $where );
				} else {
					if ($user->checkEmailAlreadyTaken ( $email )) {
						$this->view->errorMessage = "Email already taken. Please choose another one.";
						return;
					}
					$data = array ('username' => $username, 'email' => $email, 'password' => md5 ( $password ), 'registration_key' => $registrationKey, 'created' => $this->_helper->generator->generateCurrentTime () );
					
					$id = $user->insert ( $data );
				}
				unset ( $confirm );
				
				$this->_helper->email ( $email, $registrationKey );
				
				$this->_helper->message->setMsg ( $email );
				$this->_redirect ( '/user/success-register' );
				//				$this->_helper->message->setMsg($email);
			//    			$this->_redirect('/user/success-register');
			}
		}
	}
	
	public function successRegisterAction() {
		$this->view->email = $this->_helper->message->getMsg ();
	}
	
	private function login($menu) {
		$form = new LoginForm ( );
		$this->view->form = $form;
		$this->view->msg = $this->_helper->message->getMsg ();
		
		if ($this->getRequest ()->isPost ()) {
			if ($form->isValid ( $_POST )) {
				$user = new User ( );
				$data = $form->getValues ();
				
				$auth = Zend_Auth::getInstance ();
				
				$authAdapter = new Zend_Auth_Adapter_DbTable ( $user->getAdapter (), 'users', 'email', 'password', 'md5(?) AND status = "active"' );
				
				$authAdapter->setIdentity ( $data ['email'] )->setCredential ( $data ['password'] );
				$result = $auth->authenticate ( $authAdapter );
				
				if ($result->isValid ()) {
					$storage = new Zend_Auth_Storage_Session ( );
					$storage->write ( $authAdapter->getResultRowObject () );
					Zend_Registry::set ( 'userData', "aaa" );
					$this->_redirect ( '/user/index' );
				} else {
					echo "邮箱地址和密码不相符，再试试？";
				}
			}
		}
	}
	
	public function loginAction() {
		$config = Zend_Registry::get ( 'config' );
		$this->view->headScript ()->appendFile ( $config->baseurl . '/js/jquery.validate.min.js' );
		$this->view->headScript ()->appendFile ( $config->baseurl . '/js/register.js' );
		
		$this->view->pageTitle = "请您登录";
		$this->view->pageTitleClass = "login";
		$this->login ( false );
	}
	
	public function loginmenuAction() {
		
		$storage = new Zend_Auth_Storage_Session ( );
		$data = $storage->read ();
		if ($data) {
			$this->view->logged = true;
		} else {
			$this->login ( true );
		}
	}
	
	public function logoutAction() {
		$storage = new Zend_Auth_Storage_Session ( );
		$storage->clear ();
		Zend_Registry::set ( 'userData', null );
		
		$this->_redirect ( '/user/login' );
	}
	
	public function activateAction() {
		if ($this->getRequest ()->isGet ()) {
			
			$key = $this->_request->getQuery ( 'key' );
			$email = $this->_request->getQuery ( 'email' );
			
			$this->view->key = $key;
			$this->view->email = $email;
			
			$user = new User ( );
			
			if ($user->checkUserAlreadyActivated ( $email )) {
				$this->_helper->message->setMsg ( 'already active!' );
				$this->_redirect ( '/user/login' );
			} else {
				$this->_helper->message->getMsg ();
			}
			
			$data = array ('status' => 'active' );
			$where [] = "registration_key ='" . $key . "'";
			$where [] = "email='" . $email . "'";
			$user->update ( $data, $where );
			
			$storage = new Zend_Auth_Storage_Session ( );
			$storage->write ( $user->fetchRow ( $where ) );
		}
	}
	
	/**
	 * Request new friend action.
	 */
	public function friendrequestAction() {
		if ($this->_helper->user->isLoggedIn ()) {
			$user = $this->_helper->user->getUserData ();
			$form = new AddFriend ( null );
			$this->view->form = $form;
			if ($this->getRequest ()->isPost ()) {
				if ($form->isValid ( $_POST )) {
					$user = User::findById ( $user->id );
					$email = $form->getValue ( 'email' );
					$requestUser = User::findByEmail ( $email );
					$this->processAddFriend ( $user, $requestUser );
				}
			}
		}
	}
	
	/**
	 * Process add friend request.
	 * If succeed, then add request entry, 
	 * otherwise, return error.
	 * 
	 * Throw exception when:
	 * 1. add his own email as friend
	 * 2. add email which not exist in the system
	 * 
	 * @param $user user send request
	 * @param $requestUser user that want to be added
	 */
	private function processAddFriend($user, $requestUser) {
		if (isset ( $user ) && isset ( $requestUser )) {
			if ($user->id == $requestUser->id) {
				$this->view->message = '不能加自己为好友.';
				//      			$front = Zend_Controller_Front::getInstance();
			//      			$front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler());
			} else {
				$userFriendRequest = UserFriendRequest::findByUnique ( $user->id, $requestUser->id );
				if (! isset ( $userFriendRequest )) {
					$data = array ('user_id' => $user->id, 'target_user_id' => $requestUser->id, 'response' => 3, 'message_id' => null, 'created' => $this->_helper->generator->generateCurrentTime () );
					UserFriendRequest::addFriendRequest ( $data );
					$this->view->message = '好友邀请已经发送, 等待对方确认';
				} else {
					// request already been sent
					$this->view->message = '已邀请过该好友';
					//$this->_forward('error', 'error');
				}
			}
		} else {
			// didnt find user, throw error
			$this->_forward ( 'error', 'error' );
		}
	}
	
	/**
	 * Friend action.
	 */
	public function friendAction() {
	
	}
	
	/**
	 * Add friend request action.
	 */
	public function addfriendrequestAction() {
		if ($this->_helper->user->isLoggedIn ()) {
			$target_user = User::findById ( $this->_getParam ( 'uid' ) );
			$user = User::findById ( $this->_helper->user->getUserData ()->id );
			$db = Zend_Registry::get ( 'db' );
			$db->beginTransaction ();
			$this->processAddFriend ( $user, $target_user );
			$db->commit ();
		} else {
			$this->_redirect ( '/user/login' );
		}
	}
	
	/**
	 * Show user friend request action.
	 */
	public function showfriendrequestAction() {
		if ($this->_helper->user->isLoggedIn ()) {
			$user = User::findById ( $this->_helper->user->getUserData ()->id );
			$userUnprocessedFriendRequest = User::getFriendRequest ( $user, 3 );
			$this->view->userUnprocessedFriendRequest = $userUnprocessedFriendRequest;
		} else {
			$this->_redirect ( '/user/login' );
		}
	}
	
	/**
	 * Process user friend request action.
	 * Approve/deny user add friend request.
	 */
	public function processfriendrequestAction() {
		if ($this->_helper->user->isLoggedIn ()) {
			$user_id = $this->_getParam ( 'uid' );
			$db = Zend_Registry::get ( 'db' );
			$db->beginTransaction ();
			$data = array ('user_id' => $user_id, 'target_user_id' => $this->_helper->user->getUserData ()->id, 'response' => 2, 'approved_date' => $this->_helper->generator->generateCurrentTime () );
			UserFriendRequest::addFriendRequest ( $data );
			$data = array ('original_user_id' => $user_id, 'potential_user_id' => $this->_helper->user->getUserData ()->id, 'relation_type' => 2, 'alias' => null, 'created' => $this->_helper->generator->generateCurrentTime () );
			UserRelation::addOrUpdateUserRelation ( $data );
			$db->commit ();
			$this->_redirect ( 'user/showfriendrequest' );
		} else {
			$this->_redirect ( '/user/login' );
		}
	}
	
	
	/**
	 * Send public message action.
	 */
	public function sendmessageAction() {
		if ($this->_helper->user->isLoggedIn ()) {
			$sendMessage = new ProfileMessageForm( $this->_helper->user->getUserData ()->id );
			$this->view->sendMessage = $sendMessage;
			if ($this->getRequest ()->isPost ()) {
				if ($sendMessage->isValid ( $_POST )) {
					$send_user_id = $sendMessage->getValue ( 'send_user_id' );
					$target_user_id = $sendMessage->getValue ( 'target_user_id' );
					$type = $sendMessage->getValue ( 'type' );
					$comment = $sendMessage->getValue ( 'comment' );
					
					$db = Zend_Registry::get ( 'db' );
					$db->beginTransaction ();
					$data = array ('user_id' => $send_user_id, 'message' => $comment, 'created' => $this->_helper->generator->generateCurrentTime () );
					$message_id = $this->message->postMessage ( $data );
					$data = array ('message_id' => $message_id, 'target_user_id' => $target_user_id, 'type' => $type, 'created' => $this->_helper->generator->generateCurrentTime () );
					$userMessage = $this->userMessage->addUserMessage ( $data );
					// add activity log
					Activity::logActivity ( Activity::USER_MESSAGE, $send_user_id, $userMessage, $this->_helper->generator->generateCurrentTime () );
					$db->commit ();
				}
			}
		} else {
			$this->_redirect ( '/user/login' );
		}
	}
	
	/**
	 * View public message action.
	 */
	public function viewmessageAction() {
	
	}
	
	/**********************************************************************
	 *  AJAX CALLS
	 **********************************************************************/
	
	/**
	 * By Passing $email and $passwoard to check if they match
	 * Called by register.js 
	 */
	public function loginajaxAction() {
		
		$this->_helper->viewRenderer->setNoRender (); //view info disabled
		$this->_helper->getHelper ( 'layout' )->disableLayout (); //template disabled
		

		$email = $this->getRequest ()->getParam ( 'email' );
		$password = $this->getRequest ()->getParam ( 'password' );
		
		$user = new User ( );
		$auth = Zend_Auth::getInstance ();
		$authAdapter = new Zend_Auth_Adapter_DbTable ( $user->getAdapter (), 'users', 'email', 'password', 'md5(?) AND status = "active"' );
		
		$authAdapter->setIdentity ( $email )->setCredential ( $password );
		$result = $auth->authenticate ( $authAdapter );
		
		if ($result->isValid ())
			echo true;
		else
			echo false;
	}
	
	/**
	 * By Passing $email to check if it's already registered
	 * Called by register.js 
	 */
	public function checkemailajaxAction() {
		
		$this->_helper->viewRenderer->setNoRender (); //view info disabled
		$this->_helper->getHelper ( 'layout' )->disableLayout (); //template disabled
		

		$email = $this->getRequest ()->getParam ( 'email' );
		
		echo $this->user->checkEmailAlreadyTaken ( $email );
	}
	
	/**
	 * By Passing $user_id to get this user's activities
	 * Called by profile.js 
	 */
	public function findactivitiesajaxAction() {
		
		$this->_helper->viewRenderer->setNoRender (); //view info disabled
		$this->_helper->getHelper ( 'layout' )->disableLayout (); //template disabled
		
		$user_id = $this->getRequest ()->getParam ( 'user_id' );		
		echo $this->view->activities ( $user_id );
	}
	
	/**
	 * 
	 **/
	public function postmessageajaxAction() {
		
		$this->_helper->viewRenderer->setNoRender (); //view info disabled
		$this->_helper->getHelper ( 'layout' )->disableLayout (); //template disabled
		
		$post_user_id = $this->getRequest ()->getParam ( 'post_user_id' );
		$target_user_id = $this->getRequest ()->getParam ( 'target_user_id' );
		$message = $this->getRequest ()->getParam ( 'comment' );
		
		$this->profilepostmessage($post_user_id, $target_user_id, $message);
		echo $this->view->messageBoard( $target_user_id );
	}
	
	/**
	 * By Passing user_id to get this user's messageboard
	 * Called by profile.js 
	 */
	public function findmessageboardajaxAction() {
		
		$this->_helper->viewRenderer->setNoRender (); //view info disabled
		$this->_helper->getHelper ( 'layout' )->disableLayout (); //template disabled
		
		$user_id = $this->getRequest ()->getParam ( 'user_id' );
		
		echo $this->view->messageBoard ( $user_id );
	}
	
	/**
	 * Password reset action.
	 * Including:
	 * 1. initial form allow typing in email
	 * 2. second form allow type new password, if key is valid.
	 * 
	 * There are 3 cases:
	 * 1. show password reset request form, type in email and a link will be sent out
	 * 2. show password reset form, the actual form that can change the password
	 * 3. text that show if the link is expired.
	 */
	public function passwordresetAction() {
		$uid = $this->_getParam('uid');
		$key = $this->_getParam('key');
		$this->view->case = 0;
		if (isset($uid) && isset($key)) {
			
			$instance = PasswordResetAuthorization::findByKey($key);
			// only allow to reset password, if the key is FREE_TO_USE
			if ($instance->status == PasswordResetAuthorization::FREE_TO_USE) {
				$passwordResetForm = new PasswordResetForm();
				$this->view->form = $passwordResetForm;
				$this->view->case = 2;
				if ($this->getRequest ()->isPost ()) {
					if ($passwordResetForm->isValid ($_POST)) {
						$password = $passwordResetForm->getValue('password');
						$passwordConfirm = $passwordResetForm->getValue('password_confirm');
						if (isset($password) && $password == $passwordConfirm) {
							$db = Zend_Registry::get('db');
							$db->beginTransaction();
							$user = User::findById($uid);
							User::updatePassword($user, md5($password));
							PasswordResetAuthorization::updateStatusToVisited($key);
							$db->commit();
							$this->_redirect('user/login');
						} else {
							echo "Invalid password";
						}
					}
				}
			} else {
				$this->view->case = 3;
			}
		} else {
			$passwordResetRequestForm = new PasswordResetRequestForm();
			$this->view->form = $passwordResetRequestForm;
			$this->view->case = 1;
			if ($this->getRequest ()->isPost ()) {
				if ($passwordResetRequestForm->isValid ($_POST)) {
					$email = $passwordResetRequestForm->getValue('email');
					$user = User::findByEmail($email);
					if (isset($user)) {
						$config = Zend_Registry::get('config');
						$db = Zend_Registry::get('db');
						$db->beginTransaction();
						$authorizationKeyObj = PasswordResetAuthorization::addOrUpdateKey(
							$user, 
							$this->_helper->generator->generateCurrentTime()
						);
						$data = array(
							EmailMessageTemplate::TAG_PASSWORD_RESET_URL => $config->baseurl.'user/passwordreset/uid/'.$user->id.'/key/'.$authorizationKeyObj->key
						);
						MailQueue::addToQueue(
							Activity::PASSWORD_RESET_REQUEST, 
							'重设密码', 
							$user->email, 
							EmailMessageTemplate::getMessage(Activity::PASSWORD_RESET_REQUEST, $data),
							$this->_helper->generator->generateCurrentTime());
						$db->commit();
						echo 'Finished';
					}
					
				}
			}
		}		
	}
}